﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace LicenseMgr
{
    public partial class MainForm : Form
    {
        private DataSet ds1 = new DataSet();
        public MainForm()
        {
            InitializeComponent();
            //dgvProduct.DataSource = ds1;
        }

        private void btnGenSign_Click(object sender, EventArgs e)
        {
            tbPrivateXml.Text = SignedHelper.FormatXml(this.GenPrivateKey());
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //设置文件类型  
            saveFileDialog.Filter = "XML文件(*.xml)|*.xml|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            //设置文件名称：
            //saveFileDialog.FileName = DateTime.Now.ToString("yyyyMMdd") + "-" + "资产信息报表.xls";

            //设置默认文件类型显示顺序  1 xml 2 txt 3 *
            saveFileDialog.FilterIndex = 1;

            //保存对话框是否记忆上次打开的目录  
            saveFileDialog.RestoreDirectory = true;

            //点了保存按钮进入  
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.tbPrivateXmlFile.Text = saveFileDialog.FileName;
                XmlDocument xmlDoc = SignedHelper.LoadXml(tbPrivateXml.Text);
                xmlDoc.Save(tbPrivateXmlFile.Text);
            }
            this.tbPublicKey.Text = SignedHelper.FormatXml(this.GenPublicKey());
        }
        /// <summary>
        /// 生成私钥
        /// </summary>
        /// <returns></returns>
        public string GenPrivateKey()
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider(new CspParameters
            {
                Flags = CspProviderFlags.UseMachineKeyStore
            });

            string pubKey = key.ToXmlString(true);
            return pubKey;
        }
        /// <summary>
        /// 生成公钥
        /// </summary>
        /// <returns></returns>
        public string GenPublicKey()
        {
            RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(new CspParameters
            {
                Flags = CspProviderFlags.UseMachineKeyStore
            });
            //rSACryptoServiceProvider.ToXmlString()
            rSACryptoServiceProvider.FromXmlString(this.tbPrivateXml.Text);
            return rSACryptoServiceProvider.ToXmlString(false);
            //this.tbPrivateXml
        }

        private void btnOpenXml_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.InitialDirectory = "c:\\";//注意这里写路径时要用c:\\而不是c:\
            openFileDialog.Filter = "所有文件|*.*|文本文件|*.txt|XML文件|*.xml";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.tbXmlFile.Text = openFileDialog.FileName;
                //File fileOpen = new File(fName);
            }
        }

        private void btnSignXml_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.tbXmlFile.Text))
            {
                MessageBox.Show(this, "代签名XML文件不能为空！\r\n请选择要签名的XML文件！", "请选择待签名XML文件", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (string.IsNullOrEmpty(this.tbPrivateXml.Text))
            {
                MessageBox.Show(this, "私钥不能为空，\r\n请选择或生成私钥！", "私钥不能为空", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if (!File.Exists(tbXmlFile.Text))
            {
                MessageBox.Show(this, "待签名文件不存在，\r\n请选择正确的文件！", "待签名文件不存在", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            XmlDocument xmlDocument = null;

            xmlDocument = new XmlDocument();
            xmlDocument.Load(tbXmlFile.Text);

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //设置文件类型  
            saveFileDialog.Filter = " xml文件(*.xml)|*.xml|All files(*.*)|*.*";
            //设置文件名称：
            //saveFileDialog.FileName = DateTime.Now.ToString("yyyyMMdd") + "-" + "资产信息报表.xls";

            //设置默认文件类型显示顺序  1 xml 2 txt 3 *
            saveFileDialog.FilterIndex = 1;

            //保存对话框是否记忆上次打开的目录  
            saveFileDialog.RestoreDirectory = true;

            //点了保存按钮进入  
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                SignedHelper.SignFile(this.tbPrivateXml.Text, xmlDocument, saveFileDialog.FileName);
                tbSignedXmlFile.Text = saveFileDialog.FileName;
                //获得文件路径  
                //localFilePath = saveFileDialog1.FileName.ToString();
                //string filname = this.openFileDialog2.FileName;
                //获取文件名，不带路径  
                //fileNameExt = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1);  

                //获取文件路径，不带文件名  
                //FilePath = localFilePath.Substring(0, localFilePath.LastIndexOf("\\"));  

                //给文件名前加上时间  
                //newFileName = DateTime.Now.ToString("yyyyMMdd") + fileNameExt;  

                //在文件名里加字符  
                //saveFileDialog1.FileName.Insert(1,"dameng");  

                //System.IO.FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile();//输出文件  

                //fs输出带文字或图片的文件，就看需求了  
            }
        }

        

        private void btnCheckSign_Click(object sender, EventArgs e)
        {
            RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(new CspParameters
            {
                Flags = CspProviderFlags.UseMachineKeyStore
            });
            //rSACryptoServiceProvider.ToXmlString()
            rSACryptoServiceProvider.FromXmlString(tbPublicKey.Text);
            XmlDocument xmlDocument = null;

            xmlDocument = new XmlDocument();
            xmlDocument.Load(tbSignedXmlFile.Text);
            SignedXml signedXml = new SignedXml(xmlDocument);
            try
            {
                /*
                582 是 "Signature"
                595 是 "http://www.w3.org/2000/09/xmldsig#"
                下面这段代码就是获取签名数据，如果获取失败就授权异常
                 */
                XmlNode xmlNode = xmlDocument.GetElementsByTagName("Signature", "http://www.w3.org/2000/09/xmldsig#")[0];
                signedXml.LoadXml((XmlElement)xmlNode);
            }
            catch (Exception value)
            {
            }
            if (signedXml.CheckSignature(rSACryptoServiceProvider))
            {
                MessageBox.Show(this, "数据完整", "数据完整", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                //error
            } else
            {
                MessageBox.Show(this, "验证错误", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnOpenPrivateKey_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.InitialDirectory = "c:\\";//注意这里写路径时要用c:\\而不是c:\
            openFileDialog.Filter = "XML文件(*.xml)|*.xml|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.tbPrivateXmlFile.Text = openFileDialog.FileName;
                XmlDocument xmlDocument = SignedHelper.LoadXmlFile(this.tbPrivateXmlFile.Text);
                this.tbPrivateXml.Text = SignedHelper.FormatXml(xmlDocument);
                this.tbPublicKey.Text = SignedHelper.FormatXml(this.GenPublicKey());
                //File fileOpen = new File(fName);
            }

        }

        private void btnOpenSignedXml_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.InitialDirectory = "c:\\";//注意这里写路径时要用c:\\而不是c:\
            openFileDialog.Filter = "XML文件(*.xml)|*.xml|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.tbSignedXmlFile.Text = openFileDialog.FileName;
                //File fileOpen = new File(fName);
            }
        }

        private void btnSavePublicKey_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbPublicKey.Text))
            {
                MessageBox.Show(this, "公钥不能为空，\r\n请选择或生成私钥！", "公钥不能为空", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //设置文件类型  
            saveFileDialog.Filter = " xml文件(*.xml)|*.xml|All files(*.*)|*.*";
            //设置文件名称：
            //saveFileDialog.FileName = DateTime.Now.ToString("yyyyMMdd") + "-" + "资产信息报表.xls";

            //设置默认文件类型显示顺序  1 xml 2 txt 3 *
            saveFileDialog.FilterIndex = 1;

            //保存对话框是否记忆上次打开的目录  
            saveFileDialog.RestoreDirectory = true;

            //点了保存按钮进入  
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                XmlDocument xmlDoc = SignedHelper.LoadXml(tbPublicKey.Text);
                xmlDoc.Save(saveFileDialog.FileName);
            }
        }

        private void btnCopyPublicKey_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(tbPublicKey.Text);
            MessageBox.Show(this, "复制成功", "确定", MessageBoxButtons.OK);

        }

        private void llHomepage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://blog.techcave.cn");
        }

        private void btnOpenLicFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.InitialDirectory = "c:\\";//注意这里写路径时要用c:\\而不是c:\
            openFileDialog.Filter = "XML文件(*.xml)|*.xml|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.tbLicFile.Text = openFileDialog.FileName;
                //File fileOpen = new File(fName);
                var ds = this.GetDataSetByXmlpath(openFileDialog.FileName);
                ds1 = ds;
                var pro = ds.Tables["product"];
                dgvProduct.DataSource = pro;
                //var tabs = ds.Tables;
            }
        }

        public DataSet GetDataSetByXmlpath(string strXmlPath)
        {
            try
            {
                DataSet ds = new DataSet();
                //读取XML到DataSet 

                StreamReader sr = new StreamReader(strXmlPath, Encoding.Default);

                ds.ReadXml(sr);

                sr.Close();

                if (ds.Tables.Count > 0)
                    return ds;
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }

        private void btnSaveLicenseFile_Click(object sender, EventArgs e)
        {
            //SaveFileDialog sfd = new SaveFileDialog();
            MemoryStream stream = null;
            XmlTextWriter writer = null;

            try
            {
                stream = new MemoryStream();
                //从stream装载到XmlTextReader  
                writer = new XmlTextWriter(stream, Encoding.Unicode);

                //用WriteXml方法写入文件.  
                ds1.WriteXml(writer);
                int count = (int)stream.Length;
                byte[] arr = new byte[count];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(arr, 0, count);

                UnicodeEncoding utf = new UnicodeEncoding();
                var xml = utf.GetString(arr).Trim();
                tbPublicKey.Text = xml;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (writer != null) writer.Close();
            }
        }
    }
}
